function processPreviewMode(gCode, imageData, gcp) {
    if (gcp.previewMode === 3){ // 特殊的，旋转轴的直线预览
        rotateLinePreview(gCode, imageData, gcp);
        return;
    }

    switch (gcp.markMode) {
        case 0: // 平面模式
            flatPreview(gCode, imageData, gcp);
            break;
        case 1: // 扩幅模式
            break; 
        case 2: // 旋转模式(夹爪)
            clampPreview(gCode, imageData, gcp);
            break;
        case 3: // 旋转模式（滚轴）
            rollerPreview(gCode, imageData, gcp);
            break;
        default:
            throw new Error(`未知的打标模式: ${gcp.markMode}`);
    }
}

function flatPreview(gCode, imageData, gcp){
    let xLength = imageData.width * gcp.laserXBeamSize;
    let yLength = imageData.height * gcp.laserYBeamSize;
    if (gcp.isRelativeCoord){ 
        gCode.rapid({x: gcp.xOffset, y: gcp.yOffset});
        gCode.linear({x:  xLength});
        gCode.linear({y: yLength});
        gCode.linear({x: -imageData.width * gcp.laserXBeamSize});
        gCode.linear({y: -yLength});
        // 平面预览最后不回零
    } else{
        gCode.rapid({x: gcp.xOffset, y: gcp.yOffset});
        gCode.linear({x:  xLength + gcp.xOffset});
        gCode.linear({y: yLength + gcp.yOffset});
        gCode.linear({x: gcp.xOffset});
        gCode.linear({y: gcp.yOffset});
    }
}

function clampPreview(gCode, imageData, gcp){
    let aLength = imageData.width * gcp.laserABeamSizeActual;
    let yLength = imageData.height * gcp.laserYBeamSize;
    if (gcp.isRelativeCoord){
        gCode.rapid({a: gcp.aOffset, y: gcp.yOffset});
        gCode.linear({y: yLength});
        gCode.linear({a: aLength});
        gCode.linear({y: -yLength});
        gCode.linear({a: -aLength});
        gCode.rapid({a: -gcp.aOffset, y: -gcp.yOffset}); // 旋转轴预览最后要回零
    } else {
        gCode.rapid({a: gcp.aOffset, y: gcp.yOffset});
        gCode.linear({y: yLength + gcp.yOffset});
        gCode.linear({a: aLength + gcp.aOffset});
        gCode.linear({y: gcp.yOffset});
        gCode.linear({a: gcp.aOffset});
        gCode.rapid({a: 0, y: 0});
    }
}

// 滚轴需要注意 a 的旋转角度不能超出限制
// TODO: aOffset 的正负号判断
function rollerPreview(gCode, imageData, gcp){
    let maxAngle = gcp.rotateParams.gcodeMaxAngle;
    let aLength = imageData.width * gcp.laserABeamSizeActual;
    let aTimes = Math.floor(imageData.width * gcp.laserABeamSizeActual / maxAngle) ;
    let aRemain = aLength - aTimes * maxAngle
    let yLength = imageData.height * gcp.laserYBeamSize;
    
    if (gcp.isRelativeCoord){
        // 移动到起点
        let i = gcp.aOffset;
        if (i > 0){
            for (; i > maxAngle; i -= maxAngle){
            gCode.rapid({a: maxAngle})
        }
        gCode.rapid({a: i, y: gcp.yOffset});
        }
        // 1
        gCode.linear({y: yLength});
        for(let j = 0; j < aTimes; j++){
            gCode.linear({a: maxAngle});
        }
        gCode.linear({a: aRemain});
        gCode.linear({y: -yLength});
        for (let j = 0; j < aTimes; j++){
            gCode.linear({a: -maxAngle});
        }
        gCode.linear({a: -aRemain});
        i = gcp.aOffset;
        for (; i > maxAngle; i -=maxAngle){
            gCode.rapid({a: -i });
        }
        gCode.rapid({a: -i, y: -gcp.yOffset}); // 旋转轴预览最后要回零
    } else {
        let i = gcp.aOffset;
        for (; i > maxAngle; i -= maxAngle){
            gCode.rapid({a: maxAngle})
        }
        gCode.rapid({a: i, y: gcp.yOffset});
        // 1
        gCode.linear({y: yLength + gcp.yOffset});
        // 2
        for(let j = 1; j < aTimes + 1; j++){
            gCode.linear({a: maxAngle * j + gcp.aOffset});
        }
        gCode.linear({a: aLength + gcp.aOffset});
        // 3
        gCode.linear({y: gcp.yOffset});
        // 4
        for (let j = 1; j < aTimes + 1; j++){
            gCode.linear({a: aLength - (maxAngle * j) + gcp.aOffset});
        }
        gCode.linear({a: gcp.aOffset});
        // 回零
        i = gcp.aOffset;
        for (; i > maxAngle; i -=maxAngle){
            gCode.rapid({a: -i });
        }
        gCode.rapid({a: -i, y: 0}); // 旋转轴预览最后要回零
    }
}

function rotateLinePreview(gCode, imageData, gcp){
    let yLength = imageData.height * gcp.laserYBeamSize;
    if (gcp.isRelativeCoord){
        gCode.rapid({y: gcp.yOffset});
        gCode.linear({y: yLength});
        gCode.linear({y: -yLength});
    } else {
        gCode.rapid({y: gcp.yOffset});
        gCode.linear({y: yLength + gcp.yOffset});
        gCode.linear({y: gcp.yOffset});
    }
}

module.exports = {processPreviewMode};